package it.unicam.ids.pvm.data.mysql;

import it.unicam.ids.pvm.data.CassaDAO;
import it.unicam.ids.pvm.data.DAOException;
import it.unicam.ids.pvm.distributore.Lato;
import it.unicam.ids.pvm.postazione.Cassa;
import it.unicam.ids.pvm.postazione.Contante;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * La classe rappresenta un'implementazione dell'interfaccia 
 * CassaDAO, relativa al DBMS MySQL.
 * @author Luca Iachini, Valerio Iachini, Alessandro Cardenà
 *
 */
public class MySQLCassaDAO implements CassaDAO {
	final String sqlDelete = "DELETE FROM cassa WHERE lato = ?";
	final String sqlInsert = "INSERT INTO cassa (lato,c5,c10,c20,c50,e1,e2,e5,e10) VALUES (?,?,?,?,?,?,?,?,?)";
	final String sqlUpdate = "UPDATE cassa SET c5 = ?, c10 = ?, c20 = ?, c50 = ?, e1 = ?, e2 = ?, e5 = ?, e10 = ? WHERE lato = ?";
	final String sqlSelectCassa = "SELECT c5,c10,c20,c50,e1,e2,e5,e10 FROM cassa WHERE lato = ?";

	@Override
	public void delete(Lato lato) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			ps = conn.prepareStatement(sqlDelete);
			ps.setString(1, lato.name());
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException(
						"Errore nella cancellazione della cassa.");
		}
	}

	@Override
	public Cassa findByLato(Lato lato) throws DAOException {
		Cassa cassa = null;
		PreparedStatement ps = null;
		boolean error = false;
		int quantitaCassa[];
		Connection conn = MySQLDAOFactory.createConnection();
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sqlSelectCassa);
			ps.setString(1, lato.name());
			rs = ps.executeQuery();
			if (rs.next()) {
				quantitaCassa = new int[Contante.values().length];
				quantitaCassa[Contante.C5.posizione()] = rs.getInt("c5");
				quantitaCassa[Contante.C10.posizione()] = rs.getInt("c10");
				quantitaCassa[Contante.C20.posizione()] = rs.getInt("c20");
				quantitaCassa[Contante.C50.posizione()] = rs.getInt("c50");
				quantitaCassa[Contante.E1.posizione()] = rs.getInt("e1");
				quantitaCassa[Contante.E2.posizione()] = rs.getInt("e2");
				quantitaCassa[Contante.E5.posizione()] = rs.getInt("e5");
				quantitaCassa[Contante.E10.posizione()] = rs.getInt("e10");
				cassa = new Cassa(quantitaCassa);
			}
		} catch (Exception e) {
			error = true;
		} finally {
			if (ps != null)
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			if (rs != null)
				try {
					rs.close();
				} catch (SQLException e) {
					error = true;
				}
			if (error)
				throw new DAOException(
						"Errore nel recupero dei dati riguardanti la cassa.");
		}
		return cassa;
	}

	@Override
	public void insert(Cassa cassa, Lato lato) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			int[] quantitaCassa = cassa.getCassa();
			ps = conn.prepareStatement(sqlInsert);
			ps.setString(1, lato.name());
			ps.setInt(2, quantitaCassa[Contante.C5.posizione()]);
			ps.setInt(3, quantitaCassa[Contante.C10.posizione()]);
			ps.setInt(4, quantitaCassa[Contante.C20.posizione()]);
			ps.setInt(5, quantitaCassa[Contante.C50.posizione()]);
			ps.setInt(6, quantitaCassa[Contante.E1.posizione()]);
			ps.setInt(7, quantitaCassa[Contante.E2.posizione()]);
			ps.setInt(8, quantitaCassa[Contante.E5.posizione()]);
			ps.setInt(9, quantitaCassa[Contante.E10.posizione()]);
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException("Errore nell'inserimento della cassa.");
		}

	}

	@Override
	public void update(Cassa cassa, Lato lato) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			int[] quantitaCassa = cassa.getCassa();
			ps = conn.prepareStatement(sqlUpdate);
			ps.setInt(1, quantitaCassa[Contante.C5.posizione()]);
			ps.setInt(2, quantitaCassa[Contante.C10.posizione()]);
			ps.setInt(3, quantitaCassa[Contante.C20.posizione()]);
			ps.setInt(4, quantitaCassa[Contante.C50.posizione()]);
			ps.setInt(5, quantitaCassa[Contante.E1.posizione()]);
			ps.setInt(6, quantitaCassa[Contante.E2.posizione()]);
			ps.setInt(7, quantitaCassa[Contante.E5.posizione()]);
			ps.setInt(8, quantitaCassa[Contante.E10.posizione()]);
			ps.setString(9, lato.name());
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException("Errore nell'aggiornameto della cassa.");
		}

	}

}
